package com.google.code.swingonfire.border;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;

import com.google.code.swingonfire.utility.Colors;

public class ShadowCircle
{

    public static ShadowCircle create()
    {
        return create(8);
    }

    public static ShadowCircle create(int size)
    {
        return create(size, new Color(0xcf1e1700, true));
    }

    public static ShadowCircle create(int size, Color shadowColor)
    {
        return create(size, shadowColor, new Color(0x0f000000, true));
    }

    public static ShadowCircle create(int size, Color shadowColor, Color lineColor)
    {
        int offsetX = size / 8;
        int offsetY = size / 2;
        int insets = size + Math.max(Math.abs(offsetX), Math.abs(offsetY));

        return new ShadowCircle(offsetX, offsetY, size, shadowColor, Colors.translucent(shadowColor, 0), lineColor,
            new Insets(insets, insets, insets, insets));
    }

    private final int offsetX;
    private final int offsetY;
    private final int size;
    private final Color innerColor;
    private final Color outerColor;
    private final Color lineColor;
    private final Insets insets;

    public ShadowCircle(int offsetX, int offsetY, int size, Color innerColor, Color outerColor, Color lineColor,
        Insets insets)
    {
        super();

        this.offsetX = offsetX;
        this.offsetY = offsetY;
        this.size = size;
        this.innerColor = innerColor;
        this.outerColor = outerColor;
        this.lineColor = lineColor;
        this.insets = insets;
    }

    public int getOffsetX()
    {
        return offsetX;
    }

    public int getOffsetY()
    {
        return offsetY;
    }

    public int getSize()
    {
        return size;
    }

    public Color getInnerColor()
    {
        return innerColor;
    }

    public Color getOuterColor()
    {
        return outerColor;
    }

    public Color getLineColor()
    {
        return lineColor;
    }

    public Insets getInsets()
    {
        return insets;
    }

    public void paint(Graphics graphics, int x, int y, int radius)
    {
        Graphics2D g = (Graphics2D) graphics.create();
        ShadowCircleCacheKey key = new ShadowCircleCacheKey(radius, size, innerColor, outerColor);
        ShadowCircleCacheEntry entry = ShadowCircleCache.getInstance().get(key);

        g.drawImage(entry.getImage(), (x - radius - size) + offsetX, (y - radius - size) + offsetY, null);

        if (lineColor != null)
        {
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            g.setColor(lineColor);
            g.drawOval(x - radius - 1, y - radius - 1, (radius * 2) + 2, (radius * 2) + 2);
        }
    }

}
